///////////////////////////////////////////////////////////////////////////////
//
// Licensed under the MIT License
//
// Copyright (c) 2010 Chris Colinsky
// All Rights Reserved
//
// version	0.5
// http://code.google.com/p/sugarcookie/
// http://code.google.com/p/sugarcookie/wiki/License
//
////////////////////////////////////////////////////////////////////////////////

package sugarcookie.data.handlers.json {
	import com.adobe.serialization.json.JSON;
	
	import flash.events.EventDispatcher;
	
	import mx.logging.ILogger;
	import mx.logging.Log;
	
	import sugarcookie.data.handlers.IDataHandler;
	import sugarcookie.error.ApplicationError;
	import sugarcookie.events.DataEvent;
	import sugarcookie.events.GenericEvent;
	import sugarcookie.file.DataLoader;
	
	/**
	 * Composites the XMLLoader class and provides an API that works with the sugarcookie XML Schema.
	 */
	public class JSONHandler extends EventDispatcher implements IDataHandler {
		private var _log:ILogger;
		private var _isAutoLoad:Boolean = false;
		private var _jsonURI:String;
		private var _jsonLoader:DataLoader;
		private var _requestData:Object;
		private var _data:Object;
		private var _id:String = "JSON";
		
		public function JSONHandler(uri:String,requestData:Object=null) {
			super(this);
			_jsonURI = uri;
			_requestData = requestData;
			_log = Log.getLogger("sugarcookie.data.handlers.json.JSONHandler");
		}
		
		public function get autoLoad():Boolean { return _isAutoLoad; }
		public function set autoLoad(value:Boolean):void { _isAutoLoad = value; }
		
		public function get id():String { return _id; }
		public function set id(value:String):void { _id = value; }
		
		public function kill():void {
			_jsonLoader = null;
		}
		
		public function init():void {
			_jsonLoader = new DataLoader(_jsonURI,_requestData);
			_jsonLoader.addEventListener(DataLoader.ERROR,onError,false,0,true);
			_jsonLoader.addEventListener(DataLoader.STATUS,onStatus,false,0,true);
			_jsonLoader.addEventListener(DataLoader.COMPLETE,onComplete,false,0,true);
			_jsonLoader.load();
		}
		
		public function getObjectById(object_identifier:String=null):Object {
			_log.debug("searching for object identifier: "+object_identifier);
			//validate string
			var regex:RegExp = /([a-zA-Z0-9][\w.-]+\.?)+/i;
			if (!regex.test(object_identifier)) return null;
			
			//return request
			var result:Object = _data;
			var params:Array = object_identifier.split(".");
			var wasFound:Boolean = true;
			for (var c:int=0;c<params.length;c++) {
				if (wasFound) { wasFound=false; }
				else if (!wasFound) { 
					result = null;
					throw new ApplicationError("Property Not Found: "+params[c-1]); 
					break; 
				}
				for (var i:String in result) {
					if (i==params[c]) {
						result = result[i];
						wasFound = true;
						break;
					}
				}
			}
			return result;
		}
		
		private function onError(evt:GenericEvent):void {
			dispatchEvent(new DataEvent(DataEvent.ON_DATA_CHANNEL_ERROR,false,false,_id,true,evt.status));
		}
		
		private function onStatus(evt:GenericEvent):void {
			//could dispatch loading info here
		}
		
		private function onComplete(evt:GenericEvent):void {
			 _data = JSON.decode(_jsonLoader.data);
			
			if (_isAutoLoad) dispatchEvent(new DataEvent(DataEvent.ON_AUTO_LOAD_COMPLETE,false,false,_id,true));
			else dispatchEvent(new DataEvent(DataEvent.ON_DATA_CHANNEL_RETURN,false,false,_id,true));
		}
	}
}